home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / mouse01g.zip / MOUSE2G.ASM < prev    next >
Assembly Source File  |  1992-05-04  |  15KB  |  356 lines

  1.         Title   TSR Microsoft Mouse Driver - Full Version
  2. ;
  3. ;Author: G.B.Gustafson Feb 1992, gustafson@math.utah.edu.Internet.
  4. ;
  5. ;REFERENCE: Two similar mouse TSR programs exist:
  6. ;
  7. ;    A similar but different TSR is in MENUMOUS.ASM sources from
  8. ;    jmbj@whuts.ATT.COM (BITTMAN). It is located in archive MENUMOUS.ARC;
  9. ;    see below for source directory on Internet.
  10. ;
  11. ;    The MENUMOUS sources break when used with the BUF160_5.ZIP device
  12. ;    driver that expands the keyboard buffer (it does work with the
  13. ;    default keyboard buffer of length 17). The source below for the
  14. ;    keyboard buffer stuffer works with the BUF160_5.ZIP driver.
  15. ;
  16. ;    A shareware product called ARRMOUSE.ZIP is available on Internet
  17. ;    anonymous FTP to wuarchive.wustl.edu in directory ~/mirrors/msdos.
  18. ;    The author is Seth W. Comstock (Version 1.0, March 1990). It has
  19. ;    some good features and should be investigated.
  20. ;
  21. ;USE: The importance of the sources is educational value:
  22. ;
  23. ;     1. A simple, useful TSR that hooks the 2fh interrupt vector.
  24. ;     2. A keyboard buffer routine for stuffing keys. It will work
  25. ;        even if the keyboard buffer has been expanded.
  26. ;     3. Mouse driver example. Safe initialization and shutdown.
  27. ;        See notes below on the event handler.
  28. ;
  29. ;MOUSE SENSITIVITY. A curious feature in mouse code is sensitivity to
  30. ;movement: settling down on a character is subject to much error. In the
  31. ;code below this problem is attacked.
  32. ;
  33. ;    Ideally, the cursor should lock onto a line and not be bumped off
  34. ;    easily as the cursor scans left and right. Further, up and down
  35. ;    motion should lock the cursor onto a column. I should like to scan
  36. ;    up and down columns of numbers with the mouse exactly as I do with
  37. ;    the cursor keys. The code below is an attempt to realize these
  38. ;    features that falls short of perfection.
  39. ;
  40. ;MOUSE DRIVER DEFAULTS. The TSR resets the mouse driver and but sets no
  41. ;defaults for the mouse controls: X,Y sensitivity, doubler. If the TSR
  42. ;is unloaded, then the mouse driver is again reset to disable the event
  43. ;handler hook.
  44. ;
  45. ;RELEASE TSR. This TSR contains code to detect its own presence.
  46. ;Furthermore, it contains code to release it from memory. The code was
  47. ;written following the ideas of Al Williams, "DOS 5: A Developers Guide",
  48. ;page 516 (M&T Books 1992).
  49. ;
  50. ;    It is not safe to simply delete this TSR because of the mouse driver
  51. ;    event handler initialization. However, you can issue a mouse driver
  52. ;    reset and then it can be safely deleted by mark/release or resdel.
  53. ;
  54. ;WARRANTY. This source code carries no warranty. Its intended use is
  55. ;information. If you use it, then it was worth writing down: no
  56. ;permission is needed to copy and use this source. I repeat: this is not
  57. ;a software product, and it is serendipity if it happens to be useful.
  58. ;-GBG
  59. ;
  60. ;=========================Mouse Functions================================
  61. ;Mouse movement is mapped to cursor keys: up,down,left,right.
  62. ;Right button  ==> Esc Key   (ctrl-[, 27)
  63. ;Left button   ==> Enter Key (ctrl-M, 13)
  64. ;Settings here are for Znix mouse with ballistics /m2 /fdefault.pro
  65. ;Other ballistics tried and all are acceptable: /m1, /m3, /m4.
  66. ;Also tested on Merit Mouse Z-1000 (like Znix /m4 no ballistics).
  67. ;========================================================================
  68. ;
  69. code segment
  70.         org 100h
  71.         assume cs:code,ds:code,es:code
  72. begin:  jmp start
  73.  
  74. leftkey                 equ  4b00h
  75. rightkey                equ  4d00h
  76. upkey                   equ  4800h
  77. downkey                 equ  5000h
  78. retkey                  equ  1c0dh
  79. esckey                  equ  011bh
  80.  
  81. mouse                   equ  51         ;interrupt 33h
  82. resetmousedriver        equ   0         ;reset mouse driver
  83. pressmouse              equ   5         ;mouse button press status
  84. mousemotion             equ  11         ;mouse cursor motion
  85. seteventhandler         equ  12         ;set mask and event handler
  86. setsensitivity          equ  15         ;set horiz & vert sensitivity
  87. setdoublespeed          equ  19         ;set double-speed threshold
  88. eventmask               equ  0000000000001011b
  89. ;evenmask bits 0,1,4: movement, left & right press
  90.  
  91. horizontalsensitivity   dw  8           ;8=default mickeys/8 pixels
  92. verticalsensitivity     dw  16          ;16=default mickeys/8 pixels
  93. ;
  94. ;Mouse driver resets to 8 and 16 respectively with function 00h.
  95. ;Merit and Znix both worked well with settings 8,16.
  96. ;
  97. horizposition           dw   0          ;store mouse cursor position X
  98. vertposition            dw   0          ;store mouse cursor position Y
  99. ;
  100. mouseeventhandler proc far
  101.         sti
  102.         push ax
  103.         push bx
  104.         push cx
  105.         push dx
  106.         push di
  107.         push ds                 ;ds=mouse driver data segment
  108.  
  109.         push cs
  110.         pop ds                  ;cs=ds=TSR data segment
  111.         cld
  112. ;
  113. ;Press Mouse supplies: BX=button status, CX=X mickeys, DX=Y mickeys.
  114. ;                      CX and DX are signed integers: up==+, right==+.
  115. ;                      Clears all button counts on each call.
  116. ;
  117.         mov ax,pressmouse       ;get status of button press
  118.         mov bx,0                ;for left button
  119.         int mouse
  120.         and ax,1                ;Press left button?
  121.         jz check_rightbutton    ;No? Then check right button.
  122.         mov cx,retkey           ;Yes. Then plug in RETURN key.
  123.         call stuffbuffer        ;near function call
  124. check_rightbutton:
  125.         mov ax,pressmouse       ;get status of button press
  126.         mov bx,2                ;for right button
  127.         int mouse
  128.         and ax,2                ;press right button?
  129.         jz checkcursor          ;No? Then check cursor keys.
  130.         mov cx,esckey           ;Yes. Then plug in ESC key.
  131.         call stuffbuffer        ;near function call
  132. checkcursor:
  133.         mov ax,mousemotion      ;Has the mouse cursor moved?
  134.         int mouse
  135.         mov ax,horizposition    ;save new horizontal position
  136.         add ax,cx               ;cx=X coord supplied by mouse driver
  137.         mov horizposition,ax
  138.         cmp ax,0                ;Has the mouse cursor moved?
  139.         je motionvertical       ;No change, then check vertical
  140.         jg motionhorizontal     ;Make positive
  141.         not ax
  142. motionhorizontal:
  143.         mov bx,horizontalsensitivity
  144.         cmp ax,bx
  145.         jl motionvertical       ;didn't move enough for a change
  146.         cmp horizposition,0
  147.         mov cx,rightkey
  148.         jg  stuffit1            ;If positive, then stuff cursor Right
  149.         mov cx,leftkey
  150. stuffit1:
  151.         jmp stuffit2            ;Forget about vertical motion!
  152. motionvertical:
  153.         mov ax,vertposition     ;save new vertical position
  154.         add ax,dx               ;dx=Y coord supplied by mouse driver
  155.         mov vertposition,ax
  156.         cmp ax,0
  157.         je return               ;no change, all done
  158.         jg testvertsens         ;If positive, then stuff cursor Up
  159.         not ax
  160. testvertsens:
  161.         mov bx,verticalsensitivity
  162.         cmp ax,bx
  163.         jl return               ;didn't move enough for a change
  164.         cmp vertposition,0
  165.         mov cx,downkey
  166.         jg stuffit2
  167.         mov cx,upkey
  168. stuffit2:
  169.         call manystuffbuffer    ;stuff key CX into keyboard buffer
  170.         mov vertposition,0      ;reset vertical saved position
  171.         mov horizposition,0     ;reset horizontal saved position
  172. return:
  173.         pop ds
  174.         pop di
  175.         pop dx
  176.         pop cx
  177.         pop bx
  178.         pop ax
  179.         ret
  180. mouseeventhandler endp
  181.  
  182. manystuffbuffer proc near
  183. ; AX=amount in mickeys mouse cursor has moved.
  184. ; BX=sensitivity in mickeys
  185. ; CX=key scan code to stuff into keyboard buffer
  186. manyloop:
  187.         call stuffbuffer
  188.         sub ax,bx
  189.         cmp ax,bx               ;Full moves only
  190.         jge manyloop
  191.         ret
  192. manystuffbuffer endp
  193.  
  194. stuffbuffer proc near
  195.         cli                     ;Prevent interrupts from stuffing buffer
  196.         push es                 ;typeahead buffer start at *[0040:0080]
  197.         push si                 ;and end at *[0040:0082].
  198.         push di                 ;At segment 40h and offset 01ah is
  199.         push bx
  200.         mov di,40h              ;the offset into the typeahead buffer
  201.         mov es,di               ;for the character at the head. At
  202.         mov bx,es:[1ch]         ;segment 40h and offset 01ch is the
  203.         mov si,bx               ;offset into the typeahead buffer for
  204.         add bx,2                ;the last character. The buffer is full
  205.         cmp bx,es:[1ah]         ;if *[01ch]+2 == *[01ah].
  206.         je quit                 ;Full? Then don't add any more chars
  207.         cmp bx,es:[82h]         ;Offset less than end of buffer?
  208.         jl isroom               ;Yes. Then go ahead and stuff it.
  209.         mov bx,es:[80h]         ;Else wrap around to buffer start
  210. isroom:
  211.         mov es:[si],cx          ;CX=scan code to be stuffed
  212.         mov es:[1ch],bx         ;BX=new offset to last buffer character
  213. quit:   pop bx
  214.         pop di
  215.         pop si
  216.         pop es
  217.         sti                     ;let other routines stuff the buffer
  218.         ret                     ;near return
  219. stuffbuffer endp
  220.  
  221. ;
  222. ; Code below is for detection of second install and removal of TSR
  223. ; Motivated by Al Williams recommendations p 516, "Dos 5: A developers
  224. ; Guide", M&T Books 1992.
  225. ;
  226. old2fOFF        dw      0       ;Save here offset and segment
  227. old2fSEG        dw      0       ;of old multiplex 2fh interrupt vector
  228. SIG             equ     0cah    ;Signature of this TSR, user invented.
  229. KILLTSR         equ     (SIG SHL 8)+SIG+1
  230. ;
  231. new2fINT:                       ;New 2fh interrupt goes here
  232.         cmp ah,SIG              ;Is it service SIG?
  233.         jnz new2fIRET           ;No, then vector to original 2fh loc.
  234.         cmp al,SIG+1            ;Is it service SIG+1?
  235.         jz remove               ;Then remove TSR from memory.
  236.         mov al,255              ;Otherwise, return indicator -1
  237. new2fIRET:
  238.         jmp dword ptr cs:[old2fOFF]
  239. remove:
  240.         push ds
  241.         push es
  242.         push bx
  243.         push dx
  244.  
  245.         mov ax,cs
  246.         mov ds,ax
  247.         mov ax,352fh            ;Is the present 2fh vector ours?
  248.         int 21h
  249.         cmp bx,offset new2fINT
  250.         mov al,1                ;Report bad remove
  251.         jnz removeEXIT          ;Must be unchanged to remove
  252.         cli                     ;Looks Ok, let's reload 2fh vector
  253.         lds dx,dword ptr old2fOFF
  254.         mov ax,252fh            ;Replace old 2fh vector
  255.         int 21h
  256.         sti
  257.         mov ax,cs               ;Now free TSR memory
  258.         mov es,ax               ;Get PSP
  259.         mov ah,49h              ;Free DOS alloc memory
  260.         int 21h                 ;Should return al==0
  261.         jc removeEXIT           ;Error on carry
  262.         mov ax,0
  263. removeEXIT:
  264.         pop dx
  265.         pop bx
  266.         pop es
  267.         pop ds
  268.         iret
  269. ;
  270. endresident label byte
  271. ;
  272. ;All resident code is above this point.
  273. ;All code below this point gets trashed by TSR exit.
  274. ;No unload of 100h PSP area.
  275. ;
  276. ;temporary strings
  277. mesg1   db     'Mouse TSR already installed',13,10,
  278.         db     'Remove it from memory? [N]: ','$'
  279. mesg2   db     13,10,'$'
  280. mesg3   db     'Mouse TSR remains in memory','$'
  281. mesg4   db     'TSR removed from memory','$'
  282. mesg5   db     'Cannot remove TSR from memory','$'
  283. mesg6   db     'Mouse device has no software driver','$'
  284. mesg7   db     'Mouse TSR successfully installed','$'
  285. ;
  286. printstring proc near
  287.         mov ah,9
  288.         int 21h
  289.         ret
  290. printstring endp
  291. ;
  292. start:
  293.         push cs
  294.         pop ds
  295.         mov ax,(SIG SHL 8)
  296.         int 2fh
  297.         cmp al,0ffh             ;TSR loaded?
  298.         jne success             ;No, tsr not loaded.
  299.         mov dx,offset mesg1     ; 'Mouse TSR already installed',13,10,
  300.         call printstring        ; 'Remove it from memory? [N]: ','$'
  301.         mov ah,1                ;Read a key.
  302.         int 21h
  303.         push ax                 ;Then print cr/lf pair
  304.         mov dx,offset mesg2     ; 13,10,'$'
  305.         call printstring        ; to the terminal
  306.         pop ax
  307.         and al,0dfh             ;make key upper case
  308.         cmp al,'Y'              ;and test for YES
  309.         mov dx,offset mesg3     ;'Mouse TSR remains in memory','$'
  310.         jne printandquit        ;FAIL if key was not 'Y'
  311.         mov ax,resetmousedriver ;reset mouse driver to defaults
  312.         int mouse               ;so mouse driver does not hang
  313.         mov ax,KILLTSR          ;otherwise kill TSR
  314.         int 2fh                 ;using MUX interrupt
  315.         or al,al                ;which returns zero if it worked
  316.         mov dx,offset mesg4     ;'TSR removed from memory','$'
  317.         jz printandquit
  318.         mov dx,offset mesg5     ;'Cannot remove TSR from memory','$'
  319.         jmp printandquit
  320.  
  321. success:
  322.         mov ax,resetmousedriver ;reset mouse driver to defaults
  323.         int mouse
  324.         cmp ax,0                ;bx=number of buttons, not used yet
  325.         mov dx,offset mesg6     ; 'Mouse device has no software driver','$'
  326.         je printandquit         ;exit if no mouse driver loaded
  327.         mov ax,cs               ;Hook mouse driver to event handler
  328.         mov es,ax               ;es=segment of event handler
  329.         mov dx,offset mouseeventhandler
  330.         mov ax,seteventhandler  ;mouse driver function code
  331.         mov cx,eventmask        ;signal mask for interrupt
  332.         int mouse
  333.         mov ax,352fh            ;get DOS interrupt vector 2fh
  334.         int 21h
  335.         mov [old2fSEG],es       ;save segment and offset
  336.         mov [old2fOFF],bx
  337.         mov es,cs:[2ch]         ;es=environment segment
  338.         mov ah,49h              ;free DOS alloc memory
  339.         int 21h
  340.         mov dx,offset mesg7     ; 'Mouse TSR successfully installed','$'
  341.         call printstring        ;print a success message
  342.         mov ax,cs               ;adjust to data segment
  343.         mov ds,ax
  344.         mov dx,offset new2fINT  ;install new 2fh interrupt vector
  345.         mov ax,252fh            ;at routine "new2fINT" in this code seg
  346.         int 21h
  347.         mov dx,(endresident-begin+100h+15)/16
  348.         mov ax,3100h            ;save resident code & exit.
  349.         int 21h
  350. printandquit:
  351.         call printstring        ;Print string ds:dx until '$' sentinel
  352.         mov ax,4ch              ;Then normal exit to dos.
  353.         int 21h
  354. code    ends
  355.         end begin
  356.